package com.auth2server.controller;



import com.auth2server.utils.R;
import com.auth2server.vo.RequestEntitys;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.oauth2.OAuth2ClientProperties;
import org.springframework.http.*;
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.util.Base64;
import java.util.Collections;

/**
 * @author zl
 * @version 1.0
 * @date 2021/11/2 13:31
 */
@RestController
@RequestMapping("/")
public class Auth2Controller {
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private OAuth2ClientProperties oAuth2ClientProperties;
    @Autowired
    private OAuth2ProtectedResourceDetails oAuth2ProtectedResourceDetails;

    @PostMapping(value = "/login")
    public R login(@Validated @RequestBody RequestEntitys.Login login) throws Exception {
        try{
            //Http Basic 验证
            String clientAndSecret = oAuth2ClientProperties.getClientId() + ":" + oAuth2ClientProperties.getClientSecret();
            //这里需要注意为 Basic 而非 Bearer
            clientAndSecret = "Basic " + Base64.getEncoder().encodeToString(clientAndSecret.getBytes());
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.set("Authorization", clientAndSecret);

            //授权请求信息
            MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
            map.put("username", Collections.singletonList(login.getUsername()));
            map.put("password", Collections.singletonList(login.getPassword()));
            map.put("code", Collections.singletonList(login.getCode()));
            map.put("uuid", Collections.singletonList(login.getUuid()));
            map.put("grant_type", Collections.singletonList("sms_code"));
            map.put("scope", Collections.singletonList("app"));
            //HttpEntity
            HttpEntity httpEntity = new HttpEntity(map, httpHeaders);
            //获取 Token
            ResponseEntity<OAuth2AccessToken> body = restTemplate.exchange(oAuth2ProtectedResourceDetails.getAccessTokenUri(), HttpMethod.POST, httpEntity, OAuth2AccessToken.class);
            OAuth2AccessToken oAuth2AccessToken = body.getBody();
    //      System.out.println(oAuth2AccessToken.getValue());
    //      System.out.println(oAuth2AccessToken.getRefreshToken().getValue());
            return R.ok().put("data",oAuth2AccessToken);
        }catch (Exception e){
            return R.error(e.getMessage());
        }
    }
    @PostMapping("/refresh_token")
    public R refresh_token(@ApiParam(value = "刷新token",required = true) @RequestParam("refresh_token") String refresh_token){
        try{
            //Http Basic 验证
            String clientAndSecret = oAuth2ClientProperties.getClientId() + ":" + oAuth2ClientProperties.getClientSecret();
            //这里需要注意为 Basic 而非 Bearer
            clientAndSecret = "Basic " + Base64.getEncoder().encodeToString(clientAndSecret.getBytes());
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.set("Authorization", clientAndSecret);

            MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
            map.add("grant_type", "refresh_token");
            map.add("refresh_token", refresh_token);
            HttpEntity httpEntity = new HttpEntity(map, httpHeaders);
            ResponseEntity<OAuth2AccessToken> body = restTemplate.exchange(oAuth2ProtectedResourceDetails.getAccessTokenUri(), HttpMethod.POST, httpEntity, OAuth2AccessToken.class);
            OAuth2AccessToken oAuth2AccessToken = body.getBody();
//        System.out.println(oAuth2AccessToken.getValue());
//        System.out.println(oAuth2AccessToken.getRefreshToken().getValue());
            return R.ok().put("data",oAuth2AccessToken);
        }catch (Exception e){
            return R.error(e.getMessage());
        }
    }
}

